package org.jeecg.modules.flow.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.activiti.engine.delegate.DelegateTask;
import org.apache.commons.lang3.StringUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.base.BaseMap;
import org.jeecg.common.system.api.ISysBaseAPI;
import org.jeecg.modules.flow.dto.TaskPermissionConfigDto;
import org.jeecg.modules.flow.entity.FlowPermission;
import org.jeecg.modules.flow.mapper.FlowPermissionMapper;
import org.jeecg.modules.flow.service.IFlowPermissionService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

/**
 * @Description: 环节权限功能实现类
 * @Author: jeecg-boot
 * @Date: 2021-11-14
 * @Version: V1.0
 */
@Service
@Slf4j
public class FlowPermissionServiceImpl extends ServiceImpl<FlowPermissionMapper, FlowPermission> implements IFlowPermissionService {

    @Resource
    private ISysBaseAPI sysBaseAPI;

    @Override
    public TaskPermissionConfigDto getTaskPermissionConfig(String procdefId, String taskDefId, Integer cusNo, String orgId) {
        //构造查询条件
        LambdaQueryWrapper<FlowPermission> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(FlowPermission::getNodeId, taskDefId).eq(FlowPermission::getProcdefId, procdefId);

        if ((cusNo == null || cusNo <= 0) && StringUtils.isBlank(orgId)) {
            log.error("机构号和核心企业号为空");
            return null;
        }
        // 如果机构号为空,则获取核心企业下有权限的人或角色来执行
        if (StringUtils.isBlank(orgId)) {
            queryWrapper = queryWrapper
                    // 指定核心企业的客户号
                    .eq(FlowPermission::getCusNo, cusNo)
                    // 机构号为空，不然会获取到企业下的所有机构对节点的设置权限
                    .isNull(FlowPermission::getOrgNo);
        } else { // 机构号不为空的情况
            List<String> orgIds = new ArrayList<>();
            orgIds.add(orgId);
            // 获取上级机构
            Result<Map<String, List<String>>> mapResult = sysBaseAPI.queryParentIdsById(orgId);
            if (mapResult.isSuccess() && mapResult.getResult() != null) {
                // 加上级机构ID
                orgIds.addAll(mapResult.getResult().get(orgId));
            }
            queryWrapper = queryWrapper.in(FlowPermission::getOrgNo, orgIds.toArray());
        }
        // 获取权限列表
        List<FlowPermission> flowPermissionList = baseMapper.selectList(queryWrapper);
        if (flowPermissionList.isEmpty()) {
            return null;
        }
        TaskPermissionConfigDto dto = new TaskPermissionConfigDto();
        Set<String> candidateUsers = new HashSet<>();
        Set<String> candidateGroups = new HashSet<>();
        // 遍历权限列表
        flowPermissionList.forEach(flowPermission -> {
            if (StringUtils.isNotBlank(flowPermission.getCandidateUsers())) {
                candidateUsers.add(flowPermission.getCandidateUsers());
            }
            if (StringUtils.isNotBlank(flowPermission.getCandidateGroups())) {
                candidateGroups.add(flowPermission.getCandidateGroups());
            }
            if (StringUtils.isNotBlank(flowPermission.getAssignee())) {
                dto.setAssignee(flowPermission.getAssignee());
            }
        });
        dto.setCandidateUsers(candidateUsers);
        dto.setCandidateGroups(candidateGroups);
        return dto;
    }

    @Override
    public void setUserTaskPermission(DelegateTask delegateTask) {
        log.info("-----------环节权限注入-start-------------");
        // 监听任务创建事件
        String taskDefId = delegateTask.getTaskDefinitionKey();
        Set<String> variableNames = new HashSet<>();
        variableNames.add("cusNo");
        variableNames.add("orgId");
        Map<String, Object> variables = delegateTask.getVariables(variableNames);
        BaseMap baseMap = BaseMap.toBaseMap(variables);
        Integer cusNo = baseMap.get("cusNo", Integer.class);
        String orgId = baseMap.get("orgId", String.class);

        // 获取任务权限配置信息
        TaskPermissionConfigDto dto = getTaskPermissionConfig(delegateTask.getProcessDefinitionId(), taskDefId, cusNo, orgId);
        // TODO 环节未匹配到代理人、候选用户、候选组
        if (null == dto) {
            log.info("环节未匹配到权限，流程定义ID：{},任务定义ID：{}，客户号：{}，机构号：{}，", delegateTask.getProcessDefinitionId(), taskDefId, cusNo, orgId);
            Set<String> admin = new HashSet<>();
            admin.add("admin");
            delegateTask.addCandidateGroups(admin);
            return;
        }
        log.info("流程定义ID：{},任务定义ID：{}，客户号：{}，机构号：{}，", delegateTask.getProcessDefinitionId(), taskDefId, cusNo, orgId);
        // 如果代理人不为空则设置代理人
        if (StringUtils.isNotBlank(dto.getAssignee())) {
            delegateTask.setAssignee(dto.getAssignee());
        }
        // 如果候选用户不为空则设置候选用户
        if (!dto.getCandidateUsers().isEmpty()) {
            delegateTask.addCandidateUsers(dto.getCandidateUsers());
        }
        // 如果候选组不为空则设置候选组
        if (!dto.getCandidateGroups().isEmpty()) {
            delegateTask.addCandidateGroups(dto.getCandidateGroups());
        }
        log.info("-----------环节权限注入-end-------------");
    }
}
